#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include "../include/meta.h"
#include "../include/vfs_errorcodes.h"


void changep(node*);

char* mvdir(char src[100],char dest[100])
{	
	//printf("I am inside movdir");
	//printf("src:%s , dest:%s\n",src,dest);
	char result[100];
	if((strcmp(src,"/home/")==0)||(strcmp(dest,"/home/")==0))
		{
		strcpy(result,"movedir_FAILURE ");
		strcat(result,ERR_VFS_MOVEDIR_00);
		//return result;
		//char *str_to_ret = malloc (sizeof (char) * required_size)	
		sprintf(str, "%s",result);
		return str;
		}
//printf("don come here");
	if(root==NULL)
		{
		strcpy(result,"movedir_FAILURE ");
		strcat(result,ERR_VFS_MOVEDIR_08);
		sprintf(str, "%s",result);
		return str;
		//return result;
		}
	
//	printf("%s,%s\n",src,dest);
	node *srcnode11;
	srcnode11= (node *) malloc(sizeof(node));
	//if(destnode1!=NULL)
	node *destnode1 = (node *) malloc(sizeof(node));
	//if(rootnode1!=NULL)	
	node *rootnode1 = (node *) malloc(sizeof(node));
	//if(prevnode!=NULL)
	node *prev1= (node *) malloc(sizeof(node));
	node *temp1,*folder,*srcnod,*desnod;
	rootnode1 = root;
	char src1[100],dest1[100];
	
	strcpy(src1,src);
	strcpy(dest1,dest);	
	srcnod = (node*)checkpath_returnnode(src1,root);
	desnod = (node*)checkpath_returnnode(dest1,root);
	if(srcnod==NULL)
		{
		strcpy(result,"movedir_FAILURE ");
		strcat(result,ERR_VFS_MOVEDIR_01);
		sprintf(str, "%s",result);
		return str;
		
		}
 	if(desnod == NULL)
		{
		strcpy(result,"movedir_FAILURE ");
		strcat(result,ERR_VFS_MOVEDIR_02);
		sprintf(str, "%s",result);
		return str;
		//return result;
		}
	if(strcmp(fd[srcnod->index].file_type,"folder")!=0)
		{
		strcpy(result,"movedir_FAILURE ");
		strcat(result,ERR_VFS_MOVEDIR_04);
		sprintf(str, "%s",result);
		return str;
		//return result;
		}
	if(strcmp(fd[desnod->index].file_type,"folder")!=0)
		{
		strcpy(result,"movedir_FAILURE ");
		strcat(result,ERR_VFS_MOVEDIR_07);
		sprintf(str, "%s",result);
		return str;		
		}
	
	folder=desnod;
	temp1=folder->parent;
	while(folder!=NULL && temp1!=srcnod && temp1!= NULL)
	{	folder=folder->parent;
		temp1=folder->parent;
	}
	if(temp1!=NULL && temp1==srcnod)
	{	//strcpy(result,"Cannot move a folder into itself");
		strcpy(result,"movedir_FAILURE ");
		strcat(result,ERR_VFS_MOVEDIR_06);
		sprintf(str, "%s",result);
		return str;
	}

	if(desnod->lchild!=NULL)
	{
	desnod=desnod->lchild;
		if(strcmp(desnod->data,srcnod->data)==0)
		{
		strcpy(result,"movedir_FAILURE ");
		strcat(result,ERR_VFS_MOVEDIR_05);
		sprintf(str, "%s",result);
		return str;		
		//return result;
		}
		 while(desnod->rchild!=NULL && desnod->data!=srcnod->data)
		{
			desnod=desnod->rchild;
		}
		if(strcmp(desnod->data,srcnod->data)==0)
		{
		strcpy(result,"movedir_FAILURE ");
		strcat(result,ERR_VFS_MOVEDIR_05);
		sprintf(str, "%s",result);
		return str;
		//return result;
		}
	}

	//printf("\nrootnode is %s\n",rootnode1->data);
	
	
	char *token;
	token=strtok(src,"/");
	
	if(strcmp(root->data,token)!=0)
		{
		strcpy(result,"movedir_FAILURE ");
		strcat(result,ERR_VFS_MOVEDIR_01);
		sprintf(str, "%s",result);
		return str;
		}
	
	while(token!=NULL)
	{
		if(rootnode1==NULL)
		{
		strcpy(result,"movedir_FAILURE ");
		strcat(result,ERR_VFS_MOVEDIR_01);
		sprintf(str, "%s",result);
		return str;
		//return result;
		}

		else if(strcmp(rootnode1->data,token)==0) // match
		{
		 prev1 = rootnode1;
		//printf("\n prev1: %s",prev1->data);
		 rootnode1=rootnode1->lchild;	
		//printf("\n rootnode1: %s",rootnode1->data); 
		}
		else if(strcmp(rootnode1->data,token)!=0) // no match
		{

		while((rootnode1->rchild!=NULL)&&(strcmp(rootnode1->data,token)!=0))
			rootnode1=rootnode1->rchild;
		 if(strcmp(rootnode1->data,token)==0)
			{
			prev1 = rootnode1;
			rootnode1=rootnode1->lchild;
			}
		/*if((rootnode1->rchild==NULL)&&(strcmp(rootnode1->data,token)!=0))	
			{
			strcpy(result,"MOVEDIR_FAILURE");
			strcat(result,ERR_VFS_MOVEFILE_01);
			return result;
			}*/
		}
	token=strtok(NULL,"/");
	}

	srcnode11 = prev1;
	//printf("\n prev1 2 %s:",prev1->data);
	//printf("\n srcnode11 %s:",srcnode11->data);
	
	rootnode1 = root;
	token=strtok(dest,"/");
	if(strcmp(root->data,token)!=0)
		{
		strcpy(result,"movedir_FAILURE ");
		strcat(result,ERR_VFS_MOVEDIR_02);
		sprintf(str, "%s",result);
		return str;
		//return result;
		}
	
	while(token!=NULL)
	{
	if(rootnode1==NULL)
		{
		strcpy(result,"movedir_FAILURE ");
		strcat(result,ERR_VFS_MOVEDIR_02);
		sprintf(str, "%s",result);
		return str;
		//return result;
		}
			
	else if(strcmp(rootnode1->data,token)==0) // match
		{
		 prev1 = rootnode1;
		 rootnode1=rootnode1->lchild;	 
		}
	else if(strcmp(rootnode1->data,token)!=0) // no match
		{
		while((rootnode1->rchild!=NULL)&&(strcmp(rootnode1->data,token)!=0))
			rootnode1=rootnode1->rchild;
		 if(strcmp(rootnode1->data,token)==0)
			{
			prev1 = rootnode1;					
			rootnode1=rootnode1->lchild;
			}
		/*if((rootnode1->rchild==NULL)&&(strcmp(rootnode1->data,token)!=0))	
			{
			strcpy(result,"MOVEDIR_FAILURE");
			strcat(result,ERR_VFS_MOVEFILE_02);
			return result;
			}*/
		}
	token=strtok(NULL,"/");
	}

	destnode1 = prev1;

	// moving a folder into itself
	folder=destnode1;
	temp1=folder->parent;
	while(folder!=NULL && temp1!=srcnode11 && temp1!= NULL)
	{	folder=folder->parent;
		temp1=folder->parent;
	}
	if(temp1!=NULL && temp1==srcnode11)
	{	//strcpy(result,"Cannot move a folder into itself");
		strcpy(result,"movedir_FAILURE ");
		strcat(result,ERR_VFS_MOVEDIR_06);
		sprintf(str, "%s",result);
		return str;
		//return result;
	}

	// src is lchild
	temp1=srcnode11->parent;
	if(srcnode11== temp1->lchild)
		temp1->lchild= srcnode11->rchild;
	
	// src is rchild
	else{ 
		prev1=temp1->lchild;		//Changed here*********
		while(prev1->rchild!=srcnode11)
		{ prev1=prev1->rchild;}
		prev1->rchild=srcnode11->rchild;
	}
	srcnode11->rchild = NULL;

	//actual moving code
	if (fd[destnode1->index].file_type=="text")
		{
		strcpy(result,"movedir_FAILURE ");
		strcat(result,ERR_VFS_MOVEDIR_07);
		sprintf(str, "%s",result);
		return str;
		
		}
	if(destnode1->lchild==NULL)
		{destnode1->lchild=srcnode11;
		 srcnode11->parent=destnode1;
		}

	 else
		{
		destnode1=destnode1->lchild;
		 while(destnode1->rchild!=NULL && destnode1->data!=srcnode11->data)
		{
			destnode1=destnode1->rchild;
		}
		 destnode1->rchild=srcnode11;
		 srcnode11->parent=destnode1->parent;
		}
	//printf("\n move over\n");
	//printf("\n%s ",srcnode11->data);
	//printf("\n%s ",srcnode11->parent->data);

//	displayTree(root);
	changep(srcnode11);
	
	strcpy(result,"movedir_SUCCESS");
		sprintf(str, "%s",result);
		return str;
	//return result;

}

void changep(node* srcnode11)
{
	if(srcnode11!=NULL)
	{
	node* temp1=(node*) malloc(sizeof(node));
	char str1[50],path[300];
	
	
	char filename[50];
	char change_path[300];
	
	int i;int j=0;int k=0;int m=0;
	int result1,hashindex;
	
	strcpy(filename,fd[srcnode11->index].file_name);
	
	strcpy(str1,"/");
	strcat(str1,filename);
	//printf("\n str1 is :  %s ",str1);
	
	
	strcpy(path,fd[srcnode11->index].location_path);
	
	//delete hash
	
		
		//printf("\n ***************Hash before delete***********************************");
		//hash_display();
		hashindex=hash(filename);
		//printf("\n old path:%s \t %s",path,filename);
		//printf("\n ***************Hash after delete***********************************");
		result1=hash_deletion(hashindex,filename,path);
		//printf("\n result1 is %d:\n ",result1);
		//hash_display();
				

		//Deletion in bst
	//	printf("\n ***************bst b4 delete***********************************");
		//displayBstTree(bstroot);
		//printf("\nDeletion done in ");
bstroot=(bstnode*)bst_delete(bstroot,path);
		//printf("\n ***************bst after delete*********************************");
		//printf("\nDelete from bst");
		//displayBstTree(bstroot);
		
		
		temp1=srcnode11->parent;
	//	printf("\n fd[temp1->index].parent_name \t %s \t",fd[temp1->index].file_name);
		//printf("\n fd[temp1->index].parent_path \t %s \t",fd[temp1->index].location_path);
		strcpy(change_path,fd[temp1->index].location_path);
		strcat(change_path,str1);
		//printf("\n change path 1:%s \t",change_path);

	
		strcpy(fd[srcnode11->index].location_path,change_path);
		

	//use insert hash
	hashindex=hash(filename);
	//printf("\n ***************Hash after insert***********************************");
	insert_into_list(hashindex,filename,change_path);
	//hash_display();
	
	
	//printf("\n **********************************************");


	//Insert new node in bst
	//int index=4;
bstroot=(bstnode*)bst_insert(bstroot,change_path,srcnode11->index);
	//printf("\n ***************BST after insert*********************************** \n");
	
	//displayBstTree(bstroot);
	//printf("\nInsert in bst over\n");
	//printf("\n **********************************************");
	//recursive call to change sub folders
	changep(srcnode11->lchild);
	changep(srcnode11->rchild);
	//printf("\n sucess");
	//display();
	//displayBstTree(bstroot);
	}
}
